<?php

class TopUpController extends BaseController {

	// Table
	public $table = 'topup';

	// Eloquent Model
	public $model = 'Topup';

	// Base - Route Name
	public $base = 'top-up';

	// Localization
	public $local = 'en';

	// Language File Name
	public $language = 'topup';

	// Breadcrumbs 
	public $breadcrumbs = [ ['link' => 'top-up' , 'title' => 'Top-Up'] ];
	
	// Set List Data - Input, Object
	public function setListData( $data, $object ) {
		// Call the syncOrders and
		$this->_syncOrders( $object );
		$object = $this->_getTopUpList( $data, $object );
		return $object;
	}
	
	// Add List Data - Additional Data on List
	public function addListData( $data ) {
		$data['companies'] = array('All Clients');

		$branch_ids = CompanyBranch::join('company', 'company.id', '=', 'company_branch.COMPANY_id')
						->join('order', 'order.COMPANY_id', '=', 'company.id')
						->join('topup', 'topup.ORDER_id', '=', 'order.id')
						->distinct()
						->get(['company_branch.id', 'company.name', 'company_branch.name as branch_name']);
		
		foreach($branch_ids AS $branch_id){
			$branch_label = ( $branch_id->id == 'telus_manila' ) ? 'telus_flexben' : $branch_id->id;
			if(Order::where('login.BRANCH_id', '=', $branch_id->id)->join('login', 'login.id', '=', 'order.EMPLOYEE_id')->count() > 0){
				$data['companies'][$branch_id->id] = '(' . $branch_label . ')' . ucwords($branch_id->branch_name).' - '.$branch_id->name;
			}
		}
		return $data;
	}
	
	/**
	 * @author Raymond
	 * Display topup with filtering
	 * @param  $data, $object
	 * @return $object
	 */
	private function _getTopUpList( $data, $object ) {
		$object = $object->select( array('topup.LOGIN_id', 'topup.ORDER_id', 'topup.id', 'topup.status as topup_status','topup.ORDER_id',
				'login.lastname','login.firstname',
				'company_branch.name',
				'order.status as order_status', 'order.points', 'order.created_at', 'order.payment_method')
		);
	
		$object = $object->join( 'login', 'topup.LOGIN_id', '=', 'login.id' );
		$object = $object->join( 'order', 'topup.ORDER_id', '=', 'order.id' );
		$object = $object->join( 'company', 'order.COMPANY_id','=','company.id' );
		$object = $object->join( 'company_branch', 'login.BRANCH_id', '=', 'company_branch.id');
		$object = $object->where( 'order.payment_method', '<>', 'points');
		$object = $object->where( 'order.created_at', '<', DB::raw( '(NOW() - INTERVAL 24 HOUR)' ) );
		$object = $object->orderBy('order.updated_at','desc');
		
		if( !empty( $data['filter_topup_id'] ) ){
			$topup_ids = preg_split('/\r\n|[\r\n]/', $data['filter_topup_id']);
			$filtered_topup_ids = array_filter(array_unique($topup_ids));
		
			if ( !empty($filtered_topup_ids) )
				$object = $object->whereIn( 'topup.id', $filtered_topup_ids );
		}
		
		if( !empty( $data['filter_payment_method'] ) )
			$object = $object->where( 'order.payment_method', '=', $data['filter_payment_method'] );
	
		if( !empty( $data['filter_order_status'] ) ){
			$order_status = ( $data['filter_order_status'] == 8 ) ? Constant::ORDER_TOPUP :  $data['filter_order_status'];
			$object = $object->where( 'order.status', $order_status );
		}
	
		if( !empty( $data['filter_order_id'] ) ){
			$order_ids = preg_split('/\r\n|[\r\n]/', $data['filter_order_id']);
			$filtered_sales_order_ids = array_filter(array_unique($order_ids));
	
			if ( !empty($filtered_sales_order_ids) )
				$object = $object->whereIn( 'topup.ORDER_id', $filtered_sales_order_ids );
		}
	
		if( !empty( $data['filter_topup_status'] ) ) {
	
			if( $data['filter_topup_status'] == 7 )
				$object = $object->where( 'topup.status', '=', Constant::TOPUP_PENDING );
			else
				$object = $object->where( 'topup.status', '=', $data['filter_topup_status'] );
				
		}
	
		if( !empty( $data['filter_date_ref_from'] ) ) {
			$date_from = date( "Y-m-d", strtotime( $data['filter_date_ref_from'] ) );
	
			$object = $object->whereHas('topupInformation', function ( $q ) use ( $date_from ) {
				$q->where( 'date', '>=', $date_from.' 00:00:00' );
			});
		}
	
		if( !empty( $data['filter_date_ref_to'] ) ){
			$date_to = date( "Y-m-d", strtotime( $data['filter_date_ref_to'] ) );
	
			$object = $object->whereHas('topupInformation', function ( $q ) use ( $date_to ) {
				$q->where( 'topup_information.date', '<=', $date_to.' 23:59:59' );
			});
		}
	
		if( !empty( $data['filter_client'] ) )
			$object = $object->where('company_branch.id', '=', $data['filter_client'] );
	
		if(!empty($data['filter_employee_id']))
			$object = $object->where('login.id', '=', $data['filter_employee_id']);
	
		if(!empty($data['filter_employee_firstname']))
			$object = $object->where('login.firstname', 'LIKE','%' . $data['filter_employee_firstname']. '%' );
	
		if(!empty($data['filter_employee_lastname']))
			$object = $object->where('login.lastname', 'LIKE', '%' .$data['filter_employee_lastname']. '%');
	
		return $object;
	}
	
	// Process before updating data
	public function preUpdate( $data ) {
		if($data['topup_information']){
			foreach( $data['topup_information'] as $index=>$topup_info ) {

				$topup_info['amount'] = trim( $topup_info['amount'] );
				$topup_info['reference_number'] = trim( $topup_info['reference_number'] );
				$topup_info['date'] = trim( $topup_info['date'] );

				if( !is_numeric( $topup_info['amount'] ) )
					$this->error['topup_information'][$index]['amount'][] = 'Please input numbers and period only';
				
				if( $topup_info['reference_number'] == '' )
					$this->error['topup_information'][$index]['reference_number'][] = 'This field is required';
				
				$date = DateTime::createFromFormat( 'Y-m-d H:i:s', $topup_info['date'] );
				if ( !$date ) 
					$this->error['topup_information'][$index]['date'][] = 'Your date format is invalid';
			}
		}
		// Validate comment when the action is cancel or pending
		if( $data['topup_action'] == Constant::TOPUP_PENDING_ACTION ||
				$data['topup_action'] == Constant::TOPUP_CANCEL_ACTION ){
				$this->rules['comment'] = 'required';
		}
		return $data;
	}
	
public function postUpdate( $data, $object ) {
	
	// If the user choose update only it will update topup information
	if( empty( $data['topup_action'] ) ){
		
		foreach( $data['topup_information'] as $value ){
		$object->topupInformation()->where('topup_information.id', '=', $value['id'] )
				->update( array( 'reference_number' => $value['reference_number'], 'amount' => $value['amount'], 'date' => $value['date'] ) );
		}
	}
	
	else if( $data['topup_action'] == Constant::TOPUP_PENDING_ACTION ){
		$object->status = Constant::TOPUP_PENDING;
		$object->comment = $data['comment'];
		$object->save();
		
			$emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
			//Notify Employees by sending email
			Mail::later(5, 'emails.topup_status_pending', array( 'lastname' => $object->orderInformation->employee->lastname,
			'firstname'=>$object->orderInformation->employee->firstname,'order_id'=>$object->ORDER_id,
			'comment' => $object->comment,
															), function( $message ) use ($emails) {
																$message->to($emails)->subject( 'Your Order is move to pending' );
						});
			
	}
	// Cancel the Topup
	else if( $data['topup_action'] == Constant::TOPUP_CANCEL_ACTION ){
		
		$object->status= Constant::TOPUP_CANCEL;
		$object->comment = $data['comment'];
        $object->save();
        
        $update_order = Order::find( $object->ORDER_id );
        $update_order->status = Constant::ORDER_CANCELLED;
        $update_order->save();
        
        $update_order_product= new OrderProduct;
        $update_order_product->where('ORDER_id','=', $object->ORDER_id );
        $update_order_product->status = Constant::ORDER_CANCELLED;
        $update_order_product->save();
        
        $order_ids=json_encode(array($object->ORDER_id));
        $result = Webservice::callApi( 'POST', Config::get('app.api').$object->orderInformation->company->code.'/order/updateOrderStatus', [ 'id' => $order_ids, 'status'=> Constant::ORDER_CANCELLED ] );
        
        $emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
	    //Notify Employees by sending email
	    Mail::later(5, 'emails.topup_status_reject', array( 'lastname' => $object->orderInformation->employee->lastname,
	    'firstname'=>$object->orderInformation->employee->firstname,'order_id'=>$object->ORDER_id,
	    'comment' => $object->comment,
	      										), function( $message ) use ($emails) {
	                                				$message->to($emails)->subject( 'Topup Status' );
	                                							});
	    
	}
	    // Move to processing.
	   else if( $data['topup_action'] == Constant::TOPUP_PROCESSING_ACTION ){
			   	$object->status=Constant::TOPUP_APPROVED;
			   	$object->save();
		  if( $object->orderInformation->status == Constant::ORDER_CANCELLED ){
		  //	$amount=0;
		
			$amount =$object->topupInformation->sum('amount');
			$order_id=json_encode(array($object->ORDER_id));
		  	Webservice::callApi( 'POST', Config::get('app.api').$object->orderInformation->company->code.'/order-topup-credit/orderTopupCredit', [ 'id' => $order_id , 'amount'=>$amount ] );
		  	 
				  }
		  else {
				   // Save the topup information
				   foreach( $data['topup_information'] as $value ){
				           $object->topupInformation()->where('topup_information.id', '=', $value['id'] )
				           ->update( array( 'reference_number' => $value['reference_number'], 'amount' => $value['amount'], 'date' => $value['date'] ) );
				   }
				
					$update_order = Order::find( $object->ORDER_id );
					$update_order->status = $data['topup_action'];
					$update_order->updated_at = new DateTime('NOW');//date('Y-m-d H:i:s');
					$update_order->save();
		
					$update_order_product = OrderProduct::where( 'ORDER_id','=',$object->ORDER_id )
					->update( array( 'status' =>$data['topup_action'] ) );

					$order_ids=json_encode(array($object->ORDER_id));
					$result = Webservice::callApi( 'POST', Config::get('app.api').$object->orderInformation->company->code.'/order/updateOrderStatus', [ 'id' => $order_ids, 'status'=> Constant::ORDER_PROCESSING ] );

					//Notify Employees by sending email
					$emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
					Mail::later(5, 'emails.topup_status_approved', array( 'lastname' => $object->orderInformation->employee->lastname,
					'firstname'=>$object->orderInformation->employee->firstname,'order_id'=>$object->ORDER_id,
					'comment' => $object->comment,
					), function( $message ) use ($emails){
						$message->to( $emails )->subject( 'Topup Status' );
					});
		
			   	}
	   		}						
		$action= Lang::get('topup.topup_action');
		Session::flash('last_action',$action[$data['topup_action']]);
		return $data;
	}

	/**
	 * ...
	 * @author Raymond
	 * @param $object
	 * @return void
	 */
	private function _syncOrders( $object ) {
		
		$query = Order::where( 'payment_method', '<>', Constant::PAYMENT_POINTS );
		$query = $query->where( 'status', '=', Constant::ORDER_TOPUP );
		$query = $query->where( 'created_at', '<', DB::raw( '(NOW() - INTERVAL 24 HOUR)' ) );
		// has data in Topup table? don't include in new list
		if ( $topup_orders = $object->lists('ORDER_id') ) 
			$query = $query->whereNotIn( 'id', $topup_orders );

		$query = $query->where( 'archived', 0 );
		$query = $query->get( array( 'EMPLOYEE_id', 'id', 'payment_method' ) );
		// has no result? end
		if ( !$query->count() ) return;

		$new_topups = array();
		foreach( $query as $order ) {
			$new_topups[] = array(
				'LOGIN_id' => $order->EMPLOYEE_id,
				'ORDER_id' => $order->id
			);
		}
		
		$object->insert( $new_topups );
	}
	
	/**
	 * ...Cancel Order beyond 48 hours for those doesn't update topup referrence
	 * @author Raymond
	 * @param null
	 * @return void
	 */
	private function _cancelPendingTopup( $object ){
		$topup_details = $object->select('*','order.id as order_id',
				'topup.id','topup.comment','topup.updated_at as topup_updated_at',
				'login.lastname','login.firstname')
				->join('order','topup.ORDER_id','=','order.id')
				->join('login','login.id','=','order.EMPLOYEE_id')
				->where( 'topup.updated_at','<>','0000-00-00 00:00:00' )
				->where( 'order.status', '=', Constant::ORDER_TOPUP )
				->where( 'topup.status','=', Constant::TOPUP_PENDING )
				->where( 'topup.updated_at','<' ,DB::raw( '(NOW() - INTERVAL 2 DAY)' ) );
	
		$this->data['order']=[];
		if( $topup_details->count() ){
				
			$topup_details->chunk(500, function($topup_details)
			{
				foreach ($topup_details as $topup_detail)
				{
					$count=$this->_excludeHolidayAndWeekend($topup_detail->topup_updated_at);
					
					if($count >=2){
		
						 $cancel_topup = Order::find( $topup_detail->order_id );
						 $cancel_topup->status = Constant::ORDER_CANCELLED;
						 $cancel_topup->save();
						
						$order=$this->data['order'][$topup_detail->orderInformation->company->code][]= [
							'ORDER_id' => $topup_detail->order_id,
							'amount' => $topup_detail->topupInformation->sum('amount'),
						];

						$emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
						Mail::queue( 'emails.cancel_order_for_pending_topup', array( 'lastname' => $topup_detail->lastname,
						'firstname'=>$topup_detail->firstname,'order_id'=>$topup_detail->order_id,
							
								), function( $message ) use ($emails){
									$message->to( $emails )->subject( 'Cancel Order' );
								});
					}
		
				}
					
			});
		}

		if( $this->data['order'] ){
			foreach($this->data['order'] as $code=>$order) {
				
				$results = Webservice::callApi( 'POST', Config::get('app.api') . $code.'/order_topup_credit/orderTopupCredit', [ 'order' => $order ] );
				//Backtrack::debug( $results );
			}
		}


	}
	
	/**
	 * ...Cancel Order beyond 48 hours for those doesn't upload topup reference.
	 * @author Raymond
	 * @param null
	 * @return void
	 */
	private function _cancelWithNoTopupInfo( $object ){

		$topup_details = $object->select('*','order.id as order_id',
				'topup.id','topup.comment','topup.created_at as topup_created_at',
				'login.lastname','login.firstname')
				->join('order','topup.ORDER_id','=','order.id')
				->join('login','login.id','=','order.EMPLOYEE_id')
				->where( 'order.status', '=', Constant::ORDER_TOPUP )
				->where( 'topup.updated_at', '=', '0000-00-00 00:00:00' )
				->where( 'topup.status', '=', Constant::TOPUP_PENDING )
				->whereRaw( "(SELECT reference_number FROM topup_information WHERE topup.id = TOPUP_id)=0");
				//OR(SELECT COUNT(*) FROM topup_information WHERE topup.id = TOPUP_id)=0");
				//->where( 'created_at', '<', DB::raw( '(NOW() - INTERVAL 2 DAY)' ) );
		$this->data['order']=[];
		if( $topup_details->count() ){
			
			$topup_details->chunk(500, function($topup_details)
			{
				foreach ($topup_details as $topup_detail)
				{
					$count=$this->_excludeHolidayAndWeekend($topup_detail->topup_created_at);
					
					
					if($count >=2){
						
						$cancel_topup = Order::find( $topup_detail->order_id );
						$cancel_topup->status = Constant::ORDER_CANCELLED;
						$cancel_topup->save();
						
						$this->data['order'][$topup_detail->orderInformation->company->code][]= [
						'ORDER_id' => $topup_detail->order_id,
						'amount' => $topup_detail->topupInformation->sum('amount'),
						];
						
						$emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
						Mail::queue( 'emails.cancel_no_topup_info', array( 'lastname' => $topup_detail->lastname,
						'firstname'=>$topup_detail->firstname,'order_id'=>$topup_detail->order_id,
							
						), function( $message ) use ($emails){
							$message->to( $emails )->subject( 'Cancel Order' );
						});
					}
						
				}
					
			});
		}
		
		if( $this->data['order'] ){
			foreach($this->data['order'] as $code=>$order) {
				
				$results = Webservice::callApi( 'POST', Config::get('app.api') . $code.'/order_topup_credit/orderTopupCredit', [ 'order' => $order ] );
				//Backtrack::debug( $results );
			}
		}

	}
	
	/**
	 * ..Cancel the Order beyond 48 hours for the topup that was cancel
	 * @author Raymond
	 * @param $object
	 * return void
	 */
/*	private function _cancelOrderWithCancelTopup( $object ){
	
		$topup_details =$object->select('order.id as order_id',
				'topup.id as topup_id','topup.comment','topup.updated_at as topup_updated_at',
				'login.lastname','login.firstname')
				->join('order','topup.ORDER_id','=','order.id')
				->join('login','login.id','=','order.EMPLOYEE_id')
				->where( 'order.status', '=', Constant::ORDER_TOPUP )
				->where( 'topup.updated_at','<>','0000-00-00 00:00:00' )
				->where( 'topup.status','=', Constant::TOPUP_CANCEL );
		//->where( 'updated_at','<' ,DB::raw( '(NOW() - INTERVAL 2 DAY)' ) );
		$multiple_order_id=array();
		if( $topup_details->count() ){
			$topup_details->chunk(500, function($topup_details)
			{
				foreach ($topup_details as $topup_detail)
				{
					$count=$this->_excludeHolidayAndWeekend($topup_detail->topup_updated_at);
		
					if($count >=2){
						
						 $cancel_topup = Order::find( $topup_detail->order_id );
						$cancel_topup->status = Constant::ORDER_CANCELLED;
						$cancel_topup->save();
						
						
						$cancel_topup=Topup::find( $topup_detail->topup_id );
						 $cancel_topup->status = Constant::TOPUP_PENDING;
						$cancel_topup->save();
						$emails = ['glorianmond@gmail.com', 'gladys@stormbenefits.com','erika@stormbenefits.com'];
						Mail::queue( 'emails.cancel_no_topup_info', array( 'lastname' => $topup_detail->lastname,
						'firstname'=>$topup_detail->firstname,'order_id'=>$topup_detail->order_id,
							
						), function( $message ) use ($emails){
							$message->to( $emails )->subject( 'Cancel Order' );
						});
					}
		
				}
					
			});
		}

					


	}
	*/
	
	/**
	 * Exporting topup list
	 * @author Raymond
	 * @param null
	 * @return void
	 */
	public function exportOrder( ){
		// $get_data = $this->_getTopUpList( Input::all(), Topup::where( 'topup.archived', 0) ); # Commented Out Aimon 2015-03-09
		$get_data = $this->_getTopUpList( Input::all(), Topup::where( 'topup.archived','=', 0) );
		$get_topup['topup_list'] = $get_data->get();
		$get_topup['order_statuses'] = Constant::getOrderList( true );
		return View::make( 'export.topup' )->with( $get_topup );
	}
	
	/**
	 * 
	 * 
	 */
	private function _cancelClientOrder( $multiple_order_id ){
		$cancel_orders=Order::select( 'company.code','order.EMPLOYEE_id','order.id','order.status' )
		->join( 'company','order.COMPANY_id','=','company.id' )
		->whereIn( 'order.id', array( $multiple_order_id ) )
		->get();
		
		
		foreach($cancel_orders as $cancel_order ){
			dd(Config::get('app.api').'/'.$base.'/'.'/api/'.$cancel_orders->code.'/order');exit;
		//Webservice::callApi( 'POST', Config::get('app.api').'/'.$base.'/'.'/api/'.$cancel_orders->code.'/order', $cancel_orders->id );
		}
		
	}
	
	/*
	 * Add reference detail form for topup
	 * @author Geoff - 03/21/2015 - 2:10AM
	 */
	public function getReferenceManager($id){
		return View::make('top-up-manager')->with([ 
				'ORDER_id' => Topup::where('id', '=', $id)->get()->first()->ORDER_id,
				'TOPUP_id' => $id
		 ]);
	}
	
	/**
	 * Saves reference details for admin control
	 * @auhor Geoff - 03/21/2015 - 2:11AM
	 */
	public function saveReferenceDetails(){
		$error = [];
		$inputs = Input::all();
		
		if($inputs['reference_number'] == null)
			$error['reference_number'] = Lang::get('topup.error_reference_number');
		
		if($inputs['amount'] == null)
			$error['amount'] = Lang::get('topup.error_amount');
		
		if($inputs['date'] == null)
			$error['date'] = Lang::get('topup.error_date');
		
		if($inputs['image'] == null)
			$error['image'] = Lang::get('topup.error_image');
		
		if(count($error) > 0)
			return json_encode(['error' => $error, 'success' => 0]);
		
		$topupinformation = new TopupInformation;
		
		$topupinformation->TOPUP_id = $inputs['TOPUP_id'];
		$topupinformation->ORDER_id = $inputs['order_id'];
		$topupinformation->reference_number = $inputs['reference_number'];
		$topupinformation->amount = $inputs['amount'];
		$topupinformation->image = $inputs['image'];
		$topupinformation->date = date_format(date_create($inputs['date']), "Y-m-d h:i:s");
		
		$topupinformation->save();
		
		return json_encode(['success' => 1]);
	}
	
	/**
	 * POST upload of Deposit Slip for new added Topup Reference
	 * @author Geoff - 03/21/2015 - 1:31AM
	 */
	public function uploadDepositSlipRef(){
		$file = Input::file('uploadDepositSlipRef');
		$file->move(Config::get('app.lbea'), $file->getClientOriginalName());
		
		$s3 = App::make('aws')->get('s3');
		
		$s3->putObject([
			'Bucket'     => 'sb-public-rep',
			'Key'        => 'img/topup/'.$file->getClientOriginalName(),
			'SourceFile' => Config::get('app.lbea'), $file->getClientOriginalName(),
			'ACL'        => 'public-read',
		]);
		
		return json_encode([
			'field_target' => 'image',
			'image_link' => Asset::bea('image/uploads/' . $file->getClientOriginalName()), 
			'image' => $file->getClientOriginalName(), 
			'success' => 1
		]);
	}
	
	/**
	 * POST Saves new topup reference details
	 * @author Geoff - 03/21/2015
	 */
	public function saveNewReferenceDetails(){
 		// $imagepathoftopupslip = 'topup/'.$filename;
 		// sourcefile from s3: Config::get('app.tmp_dir')
 		
	}
	//Automatically cancel and send notification for employee
	public function sendEmail(){
		$topup = new Topup;
		
		$this->_cancelWithNoTopupInfo( $topup );
		$this->_cancelPendingTopup( $topup );
		//$this->_cancelOrderWithCancelTopup( $topup );
		
	}
	
	private function _excludeHolidayAndWeekend($date){
		$start = strtotime($date);
		$end = strtotime("now");
		$count = 0;
		//echo date('Y-m-d', $start). ' ';
		while(date('Y-m-d', $start) <= date('Y-m-d', $end)){
			//$count += date('N', $start) < 6 ? 1 : 0;
			//echo date('Y-m-d', $end).' ,';
			$start = strtotime("+1 day", $start);
			if( date('N', $start) < 6 ){
				$count+=1;
			
				$holidays=new Holiday;
				 $holiday=$holidays->distinct()->select('date')->where('date','LIKE','%'.date('Y-m-d', $start).'%')->count();
			
				// echo  date('Y-m-d', $start).' ,';
				if( $holiday ) $count-=1;
				
			}	

		}
		return $count;
		
	}

}